| block | time | attacker | target | profit | currency |
|---|---|---|---|---|---|
| 1900410 | 2022-05-16T03:49:24.483 | t4PVii9P… | pSor5yoN… | 7.384078 | AUSD |
| 1900628 | 2022-05-16T04:36:42.417 | tuxT4Xsi… | rWsv8gne… | 7.510548 | KAR |
| 1900700 | 2022-05-16T04:52:50.707 | tuxT4Xsi… | rWsv8gne… | -3.464697 | KAR |
| 1900703 | 2022-05-16T04:53:24.451 | tuxT4Xsi… | rh7zjB7E… | 13.347602 | KAR |
| 1907067 | 2022-05-17T04:49:48.491 | t4PVii9P… | rWsv8gne… | 58.653459 | AUSD |
| 1908565 | 2022-05-17T10:25:12.554 | t4PVii9P… | qZczJEhd… | 7.866382 | AUSD |
| 1911015 | 2022-05-17T19:27:55.174 | t4PVii9P… | rhj7UFvC… | 7.443225 | AUSD |
| 1911765 | 2022-05-17T22:12:54.707 | t4PVii9P… | orP5K1TY… | 8.357558 | AUSD |
| 1913948 | 2022-05-18T06:18:18.653 | t4PVii9P… | prXjoJxw… | 13.478991 | AUSD |
| 1921765 | 2022-05-19T11:49:54.538 | t4PVii9P… | rCAg4xz7… | 17.132460 | AUSD |
| 1922238 | 2022-05-19T13:35:00.42 | t4PVii9P… | rhj7UFvC… | 68.566996 | AUSD |
| 1922310 | 2022-05-19T13:51:18.274 | t4PVii9P… | sEzvtxEU… | 10.949293 | AUSD |
| 1924017 | 2022-05-19T20:13:06.444 | t4PVii9P… | rXBgtiMf… | 15.346327 | AUSD |
| 1933371 | 2022-05-21T07:46:18.305 | t4PVii9P… | rCAg4xz7… | 17.225126 | AUSD |
| 1935518 | 2022-05-21T15:57:30.603 | t4PVii9P… | rhj7UFvC… | 7.261952 | AUSD |
| 1946914 | 2022-05-23T10:50:24.67 | t4PVii9P… | rhj7UFvC… | 14.858049 | AUSD |
| 1947231 | 2022-05-23T12:03:00.419 | t4PVii9P… | sEzvtxEU… | 9.080646 | AUSD |
| 1948973 | 2022-05-23T18:30:12.301 | t4PVii9P… | ro1GptNJ… | 6.124731 | AUSD |
| 1962062 | 2022-05-25T19:56:30.647 | t4PVii9P… | sEYX1oGS… | 5.959103 | AUSD |
| 1962129 | 2022-05-25T20:11:36.295 | t4PVii9P… | sEYX1oGS… | 8.652670 | AUSD |
| 1963818 | 2022-05-26T02:20:06.404 | t4PVii9P… | owFyj4LU… | 6.115261 | AUSD |
| 1965724 | 2022-05-26T09:29:18.678 | t4PVii9P… | sEYX1oGS… | 5.704609 | AUSD |
| 1980481 | 2022-05-28T16:22:48.542 | t4PVii9P… | rvVGcQ7B… | 6.876634 | AUSD |
| 1986948 | 2022-05-29T16:28:18.43 | t4PVii9P… | rXBgtiMf… | 16.850850 | AUSD |
| 2023221 | 2022-06-04T07:49:30.517 | rUGkeBXo… | sZLSbtg4… | 5.759689 | AUSD |
| 2050712 | 2022-06-08T14:14:54.246 | rUGkeBXo… | rvVGcQ7B… | 17.933428 | AUSD |
Last updated: 2022-06-14 22:50:36
Date range of data: 2022-05-16T00:01:54.551 to 2022-06-15T02:22:48.427.
Sources:
Swaps:
---
title: "Acala / Karura Sandwich Attack Dashboards"
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: scroll
social: menu
source_code: embed
params:
network: Karura
window: 30
---
```{css custom1, echo=FALSE}
.dataTables_scrollBody {
max-height: 100% !important;
}
```
```{r global, include=FALSE}
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
comment = "#>"
)
library(kableExtra)
library(formattable)
library(lubridate)
library(flexdashboard)
library(DT)
library(dygraphs)
library(subscanr)
library(data.table)
library(ghql)
x <- GraphqlClient$new()
window <- params$window
endpoint <- params$endpoint
network <- params$network
swaps <- getSwaps_acala_dex(network, window)
swaps <- merge(swaps, tokens, by.x='token0', by.y='Token') %>% setnames("decimals","decimals0")
swaps[, Name := NULL]
swaps <- merge(swaps, subscanr::tokens, by.x='token1', by.y='Token') %>% setnames("decimals","decimals1")
swaps[, Name := NULL]
swaps[, adj0 := as.numeric(substr(as.character(1e20),1, as.numeric(decimals0) + 1))]
swaps[, adj1 := as.numeric(substr(as.character(1e20),1, as.numeric(decimals1) + 1))]
swaps[, token0InAmount := as.numeric(token0InAmount)]
swaps[, token1OutAmount := as.numeric(token1OutAmount)]
swaps[, price0 := as.numeric(price0) / 1e18]
swaps[, price1 := as.numeric(price1) / 1e18]
swaps[, amount0 := token0InAmount / adj0]
swaps[, amount1 := token1OutAmount / adj1]
swaps[, token0 := subscanr::fixToken(token0)]
swaps[, token1 := subscanr::fixToken(token1)]
swaps[, tradePath := subscanr::fixToken(tradePath)]
swaps[, pathLength := length(strsplit(tradePath, ",")[[1]]) - 1, by = id]
swaps[, volume0USD := amount0 * price0]
swaps[, volume1USD := amount1 * price1]
swaps[, volumeUSDFloat := (volume0USD + volume1USD) / 2]
swaps[volume0USD == 0 & volume1USD > 0, volumeUSDFloat := volume1USD]
swaps[volume1USD == 0 & volume0USD > 0, volumeUSDFloat := volume0USD]
mysort <- function(a, b) ifelse(a < b, a %+% ":" %+% b, b %+% ":" %+% a)
getPath <- function(tradePath) {
# tradePath <- swaps[1]$tradePath
tp <- strsplit(tradePath, ",")[[1]]
n <- length(tp) - 1
if (n == 3) {
return(list(mysort(tp[1],tp[2]), mysort(tp[2],tp[3]), mysort(tp[3],tp[4])))
} else if (n == 2) {
return(list(mysort(tp[1],tp[2]), mysort(tp[2],tp[3]), "NA:NA"))
}
list(mysort(tp[1],tp[2]), "NA:NA", "NA:NA")
}
swaps[, c("pair1", "pair2", "pair3") := getPath(tradePath), by = id]
swaps[, fee := volumeUSDFloat * .03]
swaps[, feeAdj := volumeUSDFloat * .03 * pathLength]
setnames(swaps, "address", "accountId")
index <- strsplit(swaps$id, "-")
index <- do.call("rbind", index)
myindex <- as.numeric(index[, 2])
swaps[, index := myindex]
setorder(swaps, block, index)
starti <- min(swaps$block)
endi <- max(swaps$block)
j <- 1
d <- list()
prof <- list()
for (i in starti:endi) {
# i <- 1829970
tmp <- swaps[block == i]
tmpn <- tmp[, .N, by = 'accountId']
# Look for the same account number 2 times in the same block
if (nrow(tmpn) >= 2 && max(tmpn$N) >= 2) {
acct <- tmp[, .N, by = 'accountId'][N >= 2, accountId]
for (account in acct) {
# account <- acct[1]
for (ii in 1:(nrow(tmp) - 2)) {
if (tmp$token0[ii] == tmp$token1[ii+2] &&
tmp$token1[ii] == tmp$token0[ii+2] &&
tmp$accountId[ii] == tmp$accountId[[ii+2]] &&
tmp$accountId[ii] != tmp$accountId[[ii+1]] &&
length(grep(tmp$token0[ii], tmp$tradePath[ii+1])) > 0 &&
length(grep(tmp$token1[ii], tmp$tradePath[ii+1])) > 0) {
d[[j]] <- tmp[, .(block, index, token0, token1, tradePath, token0InAmount, token1OutAmount, price0, price1, timestamp, accountId)][ii:(ii+2)]
prof[[j]] = data.table(block = tmp$block[ii], time = tmp$timestamp[ii], attacker = tmp$accountId[ii], target = tmp$accountId[ii+1], profit = as.numeric(tmp$token1OutAmount[ii+2]) - as.numeric(tmp$token0InAmount[ii]), currency = tmp$token0[ii])
j <- j + 1
}
} # end for ii
} # end for account
}
}
out <- rbindlist(d)
p <- rbindlist(prof)
output <- unique(p)
output[, profit := profit / 1e12]
output[, attacker := substr(attacker, 1, 8) %+% "..."]
output[, target := substr(target, 1, 8) %+% "..."]
```
### `r network` sandwich attacks in the past 30 days
```{r plot}
dygraph(output[, .N, by = as.Date(time)], main = network %+% " Sandwich Attacks") %>%
dyStackedBarChart()
```
Row
---
### Raw Data
```{r table}
knitr::kable(output, escape = FALSE) %>%
kable_styling()
```
Row
---
### Sources:
Last updated: `r Sys.time()`
Date range of data: `r min(swaps$timestamp)` to `r max(swaps$timestamp)`.
Sources:
* [SubQuery Network](https://explorer.subquery.network/)
Swaps:
* [Acala-Swap-Day-Data](https://api.subquery.network/sq/rogerjbos/acala-swap-day-data)
* [Karura-Swap-Day-Data](https://api.subquery.network/sq/rogerjbos/karura-swap-day-data)